import { html, NE } from 'nvagir'
import UserInfo from './UserInfo'
import SideBar from './SideBar'
import './MainSideBar.less'

/**
 * 用于生成一个包含用户基本信息和侧边栏列表的侧边栏组件
 *
 * @returns 页面侧边栏组件
 */
const MainSideBar = () => {
  /**
   * 菜单栏按钮点击事件处理函数
   *
   * @remarks
   * 该事件触发会使侧边栏显示、遮罩显示、菜单栏按钮消失
   */
  const showSideBarHandler = () => {
    doms.con.classList.add('side-bar-con-shown')
    doms.mask.style.display = 'block'
    doms.menuBtn.style.display = 'none'
  }

  /**
   * 遮罩点击事件处理函数
   *
   * @remarks
   * 该事件触发会使 侧边栏隐藏、遮罩隐藏、菜单栏按钮消失。这是PC端和移动端共有的使侧边栏隐藏的方式
   */
  const maskClickHandler = () => {
    doms.con.classList.remove('side-bar-con-shown')
    doms.mask.style.display = 'none'
    doms.menuBtn.style.display = 'block'
  }

  /**
   * 左滑隐藏侧边栏事件处理函数
   *
   * @remarks
   * 这是移动端独有的使侧边栏隐藏的方式
   *
   * @param e 触摸事件对象
   */
  const touchstartHandler = function (e: TouchEvent) {
    let startX: number = 0
    let endX: number = 0

    /**
     * 触摸移动事件处理函数
     *
     * @remarks
     * 用于记录触摸点离开屏幕时的水平位置，以及实现左右拖动侧边栏
     *
     * @param e 触摸事件对象
     */
    const touchmoveHandler = function (e: TouchEvent) {
      e.preventDefault()
      endX = e.touches[0].pageX

      // 实现拖动侧边栏
      doms.con.style.transition = 'none'
      if (endX != 0 && startX >= endX) {
        doms.con.style.marginLeft = -(startX - endX) + 'px'
        console.log(startX, endX, startX - endX)
      }
    }

    /**
     * 触摸结束事件处理函数
     *
     * @remarks
     * 根据拖动距离判断是将侧边栏隐藏还是复位
     */
    const touchendHandler = function () {
      if (endX != 0 && startX - endX > 40) {
        doms.con.classList.remove('side-bar-con-shown')
        doms.mask.style.display = 'none'
        doms.menuBtn.style.display = 'block'

        doms.con.removeEventListener('touchmove', touchmoveHandler)
        doms.con.removeEventListener('touchend', touchendHandler)
      } else {
        // 复位
        doms.con.style.marginLeft = ''
        doms.con.style.transition = ''
      }
    }

    startX = e.touches[0].pageX

    doms.con.addEventListener('touchmove', touchmoveHandler)
    doms.con.addEventListener('touchend', touchendHandler)
  }

  const settings = JSON.parse(
    localStorage.getItem('userSettings') ||
      JSON.stringify({
        avatarUrl: 'https://placekitten.com/200/200',
        userName: 'defaultName',
        userIntro: 'defaultIntro',
      }),
  )

  // 侧边栏主体
  // 包含了 用户信息组件、侧边栏组件
  const { el, doms } = html<{
    con: HTMLElement
    mask: HTMLElement
    menuBtn: HTMLElement
  }>`
    <aside class="side-bar-con" n@name="con">
      <div class="main-side-bar">
        ${UserInfo({
          avatarURL: settings.avatarUrl,
          userName: settings.userName,
          userIntro: settings.userIntro,
          settingPath: '/settings',
        })}
        ${SideBar([
          { iconfontName: 'icon-home', title: '广场', path: '/playGround' },
          { iconfontName: 'icon-plan', title: '学习计划', path: '/studyPlan' },
          {
            iconfontName: 'icon-share',
            title: '文章写作',
            path: '/writeArticle',
          },
        ])}
        <button class="menu-btn" n@click=${showSideBarHandler} n@name="menuBtn">
          <i class="iconfont-class icon-menu"></i>
        </button>
      </div>
      <div class="mask" n@name="mask" n@click=${maskClickHandler}></div>
    </aside>
  `

  doms.con.addEventListener('touchstart', touchstartHandler)

  const result: NE<'MainSideBar'> = { name: 'MainSideBar', el }
  return result
}

export default MainSideBar
